﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using BarCode.Common;
using System.IO;
using BarCode.Module;
using BarCode.AccessDao;
using System.Runtime.InteropServices;
using BarCode.Bean;
using System.IO.Ports;
using System.Threading;

namespace BarCode.Forms
{
    public partial class Base_BarCode : Form
    {
        private static readonly log4net.ILog LogUtil = log4net.LogManager.GetLogger(typeof(Base_BarCode));

        private bool bPart1;
        private bool bPart2;
        private bool bPart3;

        private string part1Head;
        private string part2Head;
        private string part3Head;

        private string part1Code;
        private string part2Code;
        private string part3Code;

        // 准备输入零件1
        private string part1CodePreInput = "100000010001";
        private bool bPart1Input = false;
        // 准备输入零件2
        private string part2CodePreInput = "100000010002";
        private bool bPart2Input = false;

        private int partCodeLen = 12;

        private SerialPort ComDevice = new SerialPort(); // 监视器串口
        private string stationNo = "";  // 工作区号
        private int workAmount = 0; // 工作量


        [DllImport("user32.dll")]
        public static extern bool MessageBeep(uint uType);

        public Base_BarCode()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 窗体加载
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Base_BarCode_Load(object sender, EventArgs e)
        {
            btnInput.Visible = false;
            btnInput.Enabled = false;
            lblUser.Text = GlobalVal.CurrentUser.User;
            lblStatus.Text = "当前为正常工作状态！";
            txtBarCode.Focus();
            if (GlobalVal.bolNetConnect)
            {
                btnNet.Enabled = false;
            }
            else
            {
                btnNet.Enabled = true;
            }

            // 加载配置文件
            if (!loadIniFile()) Application.Exit();          
            

            // 生成备份数据库
            string bakBarcodeMdb = GlobalVal.BK_PATH + "barcode_" + DateTime.Today.ToString("yyyyMMdd") + ".mdb";
            if (!File.Exists(bakBarcodeMdb))
            {
                if (!Directory.Exists(GlobalVal.BK_PATH))
                {
                    Directory.CreateDirectory(GlobalVal.BK_PATH);
                }
                // 复制文件
                FileHelper.CopyFile(AppDomain.CurrentDomain.BaseDirectory + "barcode.mdb", bakBarcodeMdb);
                FileHelper.CopyFile(AppDomain.CurrentDomain.BaseDirectory + "Empty_barcode.mdb", AppDomain.CurrentDomain.BaseDirectory + "barcode.mdb");
            }

            // 获取当前用户当天的工作量
            if (GlobalVal.bolNetConnect)
            {
                DB01Dao db01 = new DB01Dao(GlobalVal.ipAddressInfo.SERVICE_IP, GlobalVal.serverMysqlInfo.USERID, GlobalVal.serverMysqlInfo.USERPWD);
                workAmount = db01.getWorkAmount(GlobalVal.CurrentUser.User);
                lblAmount.Text = (workAmount + GlobalVal.offSetInfo.baseoffset).ToString();

                // 获取最新零件码信息
                BarCodeInfo latestInfo = db01.getBaseLatestInfo();
                if (latestInfo != null)
                {
                    part1Code = latestInfo.part1;
                    part2Code = latestInfo.part2;
                    part3Code = latestInfo.part3;
                }
            }
            else
            {
                BarCodeMdbDao barcodeMdbDao = new BarCodeMdbDao();
                workAmount = barcodeMdbDao.getWorkAmount(GlobalVal.CurrentUser.User);
                lblAmount.Text = (workAmount + GlobalVal.offSetInfo.baseoffset).ToString();
                barcodeMdbDao.Release();
            }
            txtBarCode.Text = "";
            txtBarCode.Focus();

            
        }

        /// <summary>
        /// 加载配置文件
        /// </summary>
        /// <returns></returns>
        private bool loadIniFile()
        {
            // 获取零件码的配置
            bPart1 = IniFileHelper.getBoolValue("Base", "Part1_Enable");
            bPart2 = IniFileHelper.getBoolValue("Base", "Part2_Enable");
            bPart3 = IniFileHelper.getBoolValue("Base", "Part3_Enable");
            if (bPart1)
            {
                part1Head = IniFileHelper.getStringValue("Base", "Part1_Head");
                if (String.IsNullOrEmpty(part1Head))
                {
                    MessageUtil.Error("零件1的开头标志未设置，请设置后重启程序。");
                    return false;
                }
            }
            if (bPart2)
            {
                part2Head = IniFileHelper.getStringValue("Base", "Part2_Head");
                if (String.IsNullOrEmpty(part2Head))
                {
                    MessageUtil.Error("零件2的开头标志未设置，请设置后重启程序。");
                    return false;
                }
            }
            if (bPart3)
            {
                part3Head = IniFileHelper.getStringValue("Base", "Part3_Head");
                if (String.IsNullOrEmpty(part3Head))
                {
                    MessageUtil.Error("零件3的开头标志未设置，请设置后重启程序。");
                    return false;
                }
            }

            partCodeLen = IniFileHelper.getIntegerValue("Base", "Part_Len");
            if (partCodeLen < 0)
            {
                MessageUtil.Error("零件码的长度设置不正确，请设置后重启程序。");
                return false;
            }

            stationNo = IniFileHelper.getStringValue("System", "Work_Station");
            if (string.IsNullOrEmpty(stationNo))
            {
                MessageUtil.Error("工位号未设置，请设置后重启程序。");
                return false;
            }

            // 加载监视器
            bool loadRet = ComUtil.LoadMonitor(ComDevice);
            if (!loadRet)
            {
                MessageUtil.Error("监视器无法连接，请设置正确串口后重启程序。");
                return false;
            }

            return true;
        }

        /// <summary>
        /// 窗体关闭
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Base_BarCode_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (GlobalVal.bolNetConnect)
            {
                GlobalVal.bolUploadSubMain = false;
                modeFunction.upload_Data("base");
            }
            Application.Exit();
        }

        /// <summary>
        /// 二维码区域单击
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void imgBarCode_Click(object sender, EventArgs e)
        {
            btnInput.Enabled = true;
            btnInput.Visible = true;
        }

        /// <summary>
        /// 二维码区域双击
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void imgBarCode_DoubleClick(object sender, EventArgs e)
        {
            btnInput.Enabled = false;
            btnInput.Visible = false;
        }

        /// <summary>
        /// 手动输入批号按钮事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnInput_Click(object sender, EventArgs e)
        {
            string tmpID = InputBox.ShowInputBox();
            if (Consts.CANCEL.Equals(tmpID))
            {
                return;
            }
            else
            {
                if ("".Equals(tmpID))
                {
                    MessageUtil.Error("批号不能为空！");
                    return;
                }

                RsBoxIdMdbDao rsboxid = new RsBoxIdMdbDao();
                int ret = rsboxid.setBoxId(tmpID);
                if (ret == 1)
                {
                    GlobalVal.BoxId = tmpID;
                    MessageUtil.Info("批号信息添加成功！");
                    btnInput.Visible = false;
                    btnInput.Visible = false;
                }
            }
        }

        /// <summary>
        /// 联通网络 按钮事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnNet_Click(object sender, EventArgs e)
        {
            DB01Dao db01 = new DB01Dao(GlobalVal.ipAddressInfo.SERVICE_IP, GlobalVal.serverMysqlInfo.USERID, GlobalVal.serverMysqlInfo.USERPWD);
            if (db01.EnableConnect() && Consts.CONNECT_SUCCESS.Equals(db01.getConnetText()))
            {
                GlobalVal.bolNetConnect = true;
                btnInput.Enabled = false;
                btnNet.Enabled = false;
            }
            else
            {
                GlobalVal.bolNetConnect = false;
                btnNet.Enabled = true;
            }
        }

        /// <summary>
        /// 二维码输入后回车事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtBarCode_KeyPress(object sender, KeyPressEventArgs e)
        {
            try
            {
                lblStatus.Text = "";
                if (e.KeyChar == (char)13)
                {
                    string inputBarCode = txtBarCode.Text;

                    if (inputBarCode.Equals(part1CodePreInput)) {
                        bPart1Input = true;
                        txtBarCode.Text = "";
                        txtBarCode.Focus();
                        lblStatus.Text = "准备输入零件码1";
                        sendInputing();
                        return;
                    }

                    if (inputBarCode.Equals(part2CodePreInput))
                    {
                        bPart2Input = true;
                        txtBarCode.Text = "";
                        txtBarCode.Focus();
                        lblStatus.Text = "准备输入零件码2";
                        sendInputing();
                        return;
                    }

                    if (bPart1 && inputBarCode.StartsWith(part1Head) && bPart1Input)
                    {
                        if (inputBarCode.Length != partCodeLen)
                        {
                            ShowInputWarn("零件码1的位数不正确！", Consts.MB_ICONASTERISK);
                            txtBarCode.Text = "";
                            txtBarCode.Focus();
                            sendFail();
                            return;
                        }
                        part1Code = inputBarCode;
                        txtBarCode.Text = "";
                        txtBarCode.Focus();
                        lblStatus.Text = "";
                        lblAmount.ForeColor = Color.Red;
                        bPart1Input = false;
                        sendInputing();
                        return;
                    }

                    if (bPart2 && inputBarCode.StartsWith(part2Head) && bPart2Input)
                    {
                        if (inputBarCode.Length != partCodeLen)
                        {
                            ShowInputWarn("零件码2的位数不正确！", Consts.MB_ICONASTERISK);
                            txtBarCode.Text = "";
                            txtBarCode.Focus();
                            sendFail();
                            return;
                        }
                        part2Code = inputBarCode;
                        txtBarCode.Text = "";
                        txtBarCode.Focus();
                        lblStatus.Text = "";
                        lblAmount.ForeColor = Color.Red;
                        bPart2Input = false;
                        sendInputing();
                        return;
                    }

                    if (bPart3 && inputBarCode.StartsWith(part3Head))
                    {
                        if (inputBarCode.Length != partCodeLen)
                        {
                            ShowInputWarn("零件码3的位数不正确！", Consts.MB_ICONASTERISK);
                            txtBarCode.Text = "";
                            txtBarCode.Focus();
                            sendFail();
                            return;
                        }
                        part3Code = inputBarCode;
                        txtBarCode.Text = "";
                        txtBarCode.Focus();
                        lblStatus.Text = "";
                        lblAmount.ForeColor = Color.Red;
                        return;
                    }


                    // 条码长度检查
                    if (inputBarCode.Length < 11 || inputBarCode.Length > 13)
                    {
                        ShowInputWarn("条码信息位数不正确！", Consts.MB_ICONASTERISK);
                        sendFail();
                        return;
                    }

                    // 11位时检查
                    if (inputBarCode.Length == 11)
                    {
                        if (inputBarCode.StartsWith("81"))
                        {
                            inputBarCode = "801" + inputBarCode.Substring(2);
                            txtBarCode.Text = inputBarCode;
                        }
                        else
                        {
                            ShowInputWarn("无效条码信息不能扫描！", Consts.MB_ICONASTERISK);
                            sendFail();
                            return;
                        }
                    }

                    // 12位时检查
                    if (inputBarCode.Length == 12 && !inputBarCode.StartsWith("7") && !inputBarCode.StartsWith("8"))
                    {
                        ShowInputWarn("无效条码信息不能扫描！", Consts.MB_ICONASTERISK);
                        sendFail();
                        return;
                    }

                    // 13位时检查
                    if (inputBarCode.Length == 13 && !inputBarCode.StartsWith("008"))
                    {
                        ShowInputWarn("无效条码信息不能扫描！", Consts.MB_ICONASTERISK);
                        sendFail();
                        return;
                    }


                    // 计数器条码开头标志
                    if (inputBarCode.StartsWith("7"))
                    {
                        DB05Dao db05 = new DB05Dao(GlobalVal.ipAddressInfo.SERVICE_IP, GlobalVal.serverMysqlInfo.USERID, GlobalVal.serverMysqlInfo.USERPWD);
                        if (db05.EnableConnect())
                        {
                            string boxId = db05.getListId(inputBarCode);
                            if (String.IsNullOrEmpty(boxId))
                            {
                                ShowInputWarn("扫描的批号信息不存在！", 0);
                                sendFail();
                                return;
                            }
                            GlobalVal.BoxId = boxId;
                            // 更新到共享数据库
                            RsBoxIdMdbDao rsboxid = new RsBoxIdMdbDao();
                            rsboxid.setBoxId(boxId);

                            // 清空输入内容
                            txtBarCode.Text = "";
                            txtBarCode.Focus();
                            lblStatus.Text = "";
                        }
                        else
                        {
                            GlobalVal.BoxId = "";
                            // 更新到共享数据库
                            RsBoxIdMdbDao rsboxid = new RsBoxIdMdbDao();
                            rsboxid.updateIdSign("0");
                            MessageUtil.Warn("由于网络不通，无法获取当前要扫描零件的批号信息！" + Environment.NewLine + "请尽快联系管理员并手动输入批号信息！");
                            // 清空输入内容
                            txtBarCode.Text = "";
                            txtBarCode.Focus();
                            lblStatus.Text = "";
                            sendFail();
                        }
                    }
                    // 机芯条码开头标志
                    else if (inputBarCode.StartsWith("8") || inputBarCode.StartsWith("008"))
                    {
                        if (String.IsNullOrEmpty(txtDiaphragm.Text))
                        {
                            MessageUtil.Warn("膜片编号不能为空！");
                            // 清空输入内容
                            txtBarCode.Text = "";
                            txtBarCode.Focus();
                            lblStatus.Text = "";
                            sendFail();
                            return;
                        }

                        //// 获取批号
                        //RsBoxIdMdbDao rsboxid = new RsBoxIdMdbDao();
                        //GlobalVal.BoxId = rsboxid.getBoxId();
                        //if (String.IsNullOrEmpty(GlobalVal.BoxId))
                        //{
                        //    MessageUtil.Warn("未设置零件批号信息，请扫描或输入批号信息！");
                        //    // 清空输入内容
                        //    txtBarCode.Text = "";
                        //    txtBarCode.Focus();
                        //    lblStatus.Text = "";
                        //    return;
                        //}

                        if (bPart1 && String.IsNullOrEmpty(part1Code))
                        {
                            ShowInputWarn("零件1的条码未扫描！", Consts.MB_ICONASTERISK);
                            sendFail();
                            return;
                        }
                        if (bPart2 && String.IsNullOrEmpty(part2Code))
                        {
                            ShowInputWarn("零件2的条码未扫描！", Consts.MB_ICONASTERISK);
                            sendFail();
                            return;
                        }
                        if (bPart3 && String.IsNullOrEmpty(part3Code))
                        {
                            ShowInputWarn("零件3的条码未扫描！", Consts.MB_ICONASTERISK);
                            sendFail();
                            return;
                        }

                        // 保存条码信息
                        BarCodeMdbDao barcodeMdbDao = new BarCodeMdbDao();
                        try
                        {
                            BarCodeInfo barCodeInfo = barcodeMdbDao.getBarCodeById(inputBarCode);
                            if (barCodeInfo == null)
                            {
                                // 插入
                                barCodeInfo = new BarCodeInfo();
                                barCodeInfo.barcodeID = inputBarCode;
                                barCodeInfo.Operator_Name = GlobalVal.CurrentUser.User;
                                barCodeInfo.OpDt = DateTime.Now;
                                barCodeInfo.mp_number = txtDiaphragm.Text;
                                barCodeInfo.boxid = GlobalVal.BoxId;
                                barCodeInfo.part1 = part1Code;
                                barCodeInfo.part2 = part2Code;
                                barCodeInfo.part3 = part3Code;
                                barcodeMdbDao.insertBarCode(barCodeInfo);
                            }
                            else
                            {
                                // 更新
                                barCodeInfo.barcodeID = inputBarCode;
                                barCodeInfo.Operator_Name = GlobalVal.CurrentUser.User;
                                barCodeInfo.OpDt = DateTime.Now;
                                barCodeInfo.mp_number = txtDiaphragm.Text;
                                barCodeInfo.boxid = GlobalVal.BoxId;
                                barCodeInfo.part1 = part1Code;
                                barCodeInfo.part2 = part2Code;
                                barCodeInfo.part3 = part3Code;
                                barcodeMdbDao.updateBarCode(barCodeInfo);
                            }
                            barcodeMdbDao.Release();
                        }
                        catch (Exception ex)
                        {
                            LogUtil.Error("本地数据库处理异常", ex);
                            // 清空输入内容
                            txtBarCode.Text = "";
                            txtBarCode.Focus();
                            lblStatus.Text = "";
                            sendFail();
                            return;
                        }

                        if (GlobalVal.bolNetConnect)
                        {
                            // 上传数据
                            GlobalVal.bolUploadSubMain = false;
                            modeFunction.upload_Data("base");
                            lblStatus.Text = "";


                        }
                        // 获取当前用户当天的工作量
                        if (GlobalVal.bolNetConnect)
                        {
                            // 获取偏移量信息
                            DB01Dao db01 = new DB01Dao(GlobalVal.ipAddressInfo.SERVICE_IP, GlobalVal.serverMysqlInfo.USERID, GlobalVal.serverMysqlInfo.USERPWD);
                            GlobalVal.offSetInfo.baseoffset = db01.getOffSetValue(Consts.WORK_POSITION_BASE);
                            workAmount = db01.getWorkAmount(GlobalVal.CurrentUser.User);
                            lblAmount.Text = (workAmount + GlobalVal.offSetInfo.baseoffset).ToString();
                        }
                        else
                        {
                            barcodeMdbDao = new BarCodeMdbDao();
                            workAmount = barcodeMdbDao.getWorkAmount(GlobalVal.CurrentUser.User);
                            lblAmount.Text = (workAmount + GlobalVal.offSetInfo.baseoffset).ToString();
                            barcodeMdbDao.Release();
                        }
                        // 清空输入内容
                        //part1Code = "";
                        //part2Code = "";
                        //part3Code = "";
                        txtBarCode.Text = "";
                        txtBarCode.Focus();
                        lblAmount.ForeColor = Color.Black;
                        sendSuccess(workAmount);
                    }
                }
            }
            catch (Exception ex)
            {
                LogUtil.Error(ex);
            }
        }

        /// <summary>
        /// 输入有误时弹框显示
        /// </summary>
        /// <param name="msg"></param>
        private void ShowInputWarn(string msg, uint beep)
        {
            txtBarCode.Text = "";
            txtBarCode.Focus();
            lblStatus.Text = msg;
            if (beep > 0)
            {
                MessageBeep(beep);
            }
        }


        private bool LoadMonitor(string portName)
        {
            ComDevice.PortName = portName;
            ComDevice.BaudRate = 9600;
            ComDevice.Parity = Parity.Even;
            ComDevice.DataBits = 8;
            ComDevice.StopBits = StopBits.One;
            try
            {
                ComDevice.Open();
                return true;
            }
            catch (Exception ex)
            {
                lblStatus.Text = ex.Message;
                LogUtil.Error("串口打开异常", ex);
                return false;
            }

        }

        /// <summary>
        /// 发送成功指令
        /// </summary>
        /// <param name="workAmount"></param>
        private void sendSuccess(int workAmount)
        {
            try
            {
                string sendCode = ComUtil.createSuccessCode(stationNo, workAmount);
                bool sendRet = false;
                int sendCnt = 0;
                do
                {
                    Application.DoEvents();
                    sendRet = ComUtil.sendData(ComDevice, sendCode);
                    Application.DoEvents();
                    sendCnt++;

                } while (!sendRet && sendCnt < 3);

            }
            catch (Exception ex)
            {
                LogUtil.Error("发送成功指令异常发生", ex);
            }
        }

        /// <summary>
        /// 发送失败指令
        /// </summary>
        /// <param name="workAmount"></param>
        private void sendFail()
        {
            try
            {
                string sendCode = ComUtil.createFailCode(stationNo, workAmount);
                bool sendRet = false;
                int sendCnt = 0;
                do
                {
                    Application.DoEvents();
                    sendRet = ComUtil.sendData(ComDevice, sendCode);
                    Application.DoEvents();
                    sendCnt++;

                } while (!sendRet && sendCnt < 3);

                // 1秒后发送停止警报命令
                Thread.Sleep(1000);
                sendStopWarn();
            }
            catch (Exception ex)
            {
                LogUtil.Error("发送失败指令异常发生", ex);
            }
        }

        /// <summary>
        /// 发送停鸣指令
        /// </summary>
        private void sendStopWarn()
        {
            try
            {
                string sendCode = ComUtil.createStopWarnCode(stationNo, workAmount);
                bool sendRet = false;
                int sendCnt = 0;
                do
                {
                    Application.DoEvents();
                    sendRet = ComUtil.sendData(ComDevice, sendCode);
                    Application.DoEvents();
                    sendCnt++;

                } while (!sendRet && sendCnt < 3);
            }
            catch (Exception ex)
            {
                LogUtil.Error("发送停鸣指令异常发生", ex);
            }
        }


        /// <summary>
        /// 发送输入中指令
        /// </summary>
        /// <param name="workAmount"></param>
        private void sendInputing()
        {
            try
            {
                string sendCode = ComUtil.createInputingCode(stationNo, workAmount);
                bool sendRet = false;
                int sendCnt = 0;
                do
                {
                    Application.DoEvents();
                    sendRet = ComUtil.sendData(ComDevice, sendCode);
                    Application.DoEvents();
                    sendCnt++;

                } while (!sendRet && sendCnt < 3);

            }
            catch (Exception ex)
            {
                LogUtil.Error("发送输入中指令异常发生", ex);
            }
        }
    }
}
